/*
 * $Id: Exec.java 3 2007-12-07 01:24:30Z rasan.rasch $
 *
 * Copyright (c) 2002-2006 UC Regents
 * 
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names
 * of the UC Regents and the University of California are not used in any
 * advertising or publicity relating to the software without the specific,
 * prior written permission of the University of California.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY
 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
 * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOFTWARE.
 */

package org.cdl.noid;

import java.io.*;
import java.util.ArrayList;

/** 
 * Exec is a class that runs external commands.  It stores the
 * stdout and stderr of the process in ArrayList objects.  Exec
 * also allows you to write to the stdin of the process.
 * 
 * @author  Rasan Rasch (rasan@nyu.edu)
 * @version $Revision: 3 $
 */
public class Exec {

	ArrayList<String> output;
	ArrayList<String> error;

	public boolean exec(String command, ArrayList<String> input) {
		int exitValue = -1;
		try {
			Process process = Runtime.getRuntime().exec(command);

			OutputStream stdin = process.getOutputStream();
			InputStream stdout = process.getInputStream();
			InputStream stderr = process.getErrorStream();

			// Create threads for reading stdout and stderr
			StreamReader outputReader = new StreamReader(stdout, output);
			StreamReader errorReader  = new StreamReader(stderr, error);
			
			// kick off threads
			outputReader.start();
			errorReader.start();

			// write input to stdin
			PrintStream out = new PrintStream(stdin);
			for (int i = 0; i < input.size(); i++) {
				out.println(input.get(i));
			}
			out.close();
			
			exitValue = process.waitFor();

			outputReader.join();
			errorReader.join();
			
		} catch(Throwable ex) {
			System.err.println(ex.getMessage());
		}
		
		return exitValue == 0;
	}
}


class StreamReader extends Thread {
	boolean done = false;
	InputStream inputStream;
	ArrayList<String> output;

	public StreamReader(InputStream inputStream, ArrayList<String> output) {
		this.inputStream = inputStream;
		this.output = output;
	}

	public void run() {
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(
						inputStream));
			String line;
			while (!done && ((line = in.readLine()) != null)) {
				output.add(line);
			}
			in.close();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public void stopReading() {
		done = true;
	}
}
